#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 时间     : 2018-12-16 01:42:29
# 作者     : DL (584054432@qq.com)
# 网址     : https://gitee.com/dingliangPython/
# 软件版本 : Python3.6.5
# 功能     ：

from IPy import IP
from ping3 import ping
from threading import Thread
import IPy,time,os,csv

class Ping(object):
    """docstring for Ping"""
    def __init__(self,log=print):
        super(Ping, self).__init__()
        self.log=log
        print(self.log,dir(self.log))
    def is_ip(self,ipaddress):
        '''判断IP是否是一个合法的单播地址'''
        def judgement(IP):
            rec=True
            IP = [int(x) for x in IP.split('.') if x.isdigit()]
            if len(IP) == 4:
                if (0 < IP[0] < 223 and IP[0] != 127 and IP[1] < 256 and IP[2] < 256 and 0 < IP[3] < 255):
                   pass
                else:
                    rec=False
            else:
                rec=False
            return rec
        rec=True
        if isinstance(ipaddress,list) or isinstance(ipaddress,tuple):
            for IP in ipaddress:
                if not judgement(IP):
                    rec=False
                    break
            return rec
        else:
            return judgement(ipaddress)
    # 测试网络通畅
    def scan_ping(self,ip,recvice={},timeout=1):
        """[summary]

        [测试网络通畅]

        Args:
            ip: [description]
            recvice: [存储ping值] (default: {{}})
            timeout: [超时时限] (default: {1})
        Returns:
            [ping值]
            [type]
        """
        rec=ping(ip,timeout)
        recvice.setdefault(ip,rec)
        return rec
    # 扫描ip
    def scan_ip(self,ip,ip_number=None,timeout=3,ping_timeout=1):
        """[summary]

        [扫描IP地址]

        Args:
            ip: [ip地址，或地址列表] (default: {None})
            ip_number: [ip数量，ip地址为开始地址] (default: {None})
            log: [日志函数,默认是print] (default: {print})
            timeout: 扫描超时,等待线程结果的时间，非ping的超时
        """
        # 存储扫描结果
        a=time.clock()
        T={}
        #判读IP地址合法性
        if self.is_ip(ip):
            pass
        else:
            self.log.error("当前IP不合法，请检测IP地址或IP列表:%s，地址数量：%s"%(ip,ip_number if ip_number else len(ip) if isinstance(ip,list)else 1))
            return None
        # 解析IP、IP数量
        ip_list=[]
        if isinstance(ip,str) and not ip_number:
            ip=IP(ip)
            ip_list= [str(v) for v in ip]  if len(ip)>=1 else None
        elif isinstance(ip,list) or isinstance(ip,tuple) :
            ip_list= [str(IP(v)) for v in ip]
        elif ip_number:
            ip=IP(ip).int()
            ip_list= [ IPy.intToIp(ip+v,4) for v in range(int(ip_number))]if  ip else None
        #扫描IP,IPlist
        if not ip_list :
            self.log.error('IP地址异常，请检测IP地址，地址列表，或地址数量')
            return None
        b=time.clock()
        for k,v in enumerate(ip_list):
            #self.log.info("扫描第%s个IP,地址：%s 等待扫描结果。。。"%(k+1,v))
            th=Thread(target=self.scan_ping, name=v, args=(v,T,ping_timeout,))
            th.start()
        self.log.debug("开启线程数耗时：%s"%(time.clock()-b))
        time.sleep(timeout)
        return T

    #扫描文件内ip
    def scan_file(self,file='./config/IP_Address.csv'):
        if os.path.isfile(file):
            file=os.path.abspath(file)
            with open(file) as f:
                ip_list=[v for v in csv.reader(f) if v[0].isdigit()]
                ip=[v[1] for v in ip_list ]
                self.log.debug("扫描ip地址:%s,数量:%s"%(ip,len(ip)))
                rec=self.scan_ip(ip)
                table={}
                _=[table.setdefault(v[1],{'v':rec[v[1]],'name':v[2],'mid':int(v[3])}) for v in ip_list]
                self.log.debug("扫描结果:%s"%table)
                return table
        else:
            self.log.error.error("当前文件:%s,不是一个有效的scv文件"%file)

if __name__ == '__main__':
    import ReadConfig,log,time
    config=ReadConfig.Config('./config/config.ini')
    coninfo=config.read()
    logg=log.Logger(coninfo['Log'])
    app=Ping(logg.write)
    #扫描ip或ip列表
    a=app.scan_ip(['172.31.2.1','172.31.2.4'])
    print(a)

    # 扫描文件
    b=app.scan_file()